package com.lenovo.nova.util.graphics;

import java.lang.reflect.Field;
import java.util.ArrayList;

import android.graphics.*;
import com.lenovo.nova.util.debug.ObjectUtil;
import com.lenovo.nova.util.debug.ToastAlertUtil;
import com.lenovo.nova.util.debug.slog;

import android.graphics.Bitmap.Config;
import android.graphics.Paint.FontMetrics;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.view.View;

public class BitmapUtil {
	/**
	 * Recorder alpha when scan bitmap
	 */
	private int mLastAlphaValue = 0;
	
	/**
	 * the same times of {@link #mLastAlphaValue} and alpha when scan bitmap
	 */
	private int mSameTimes = 0;
	
	/**
	 * it is used to calculate scan direction
	 */
	private int mLastPosition = 0;
	
	private Bitmap mBitmap;

	/**
	 * count of alpa same
	 */
	private int SAME_COUNT = 10 ;

	private boolean DEBUG = false;
	
	public BitmapUtil(Drawable draw) {
		if(draw instanceof BitmapDrawable){
			mBitmap = ((BitmapDrawable) draw).getBitmap();
		}
		if(draw instanceof NinePatchDrawable){
			//get the bitmap value for NinePatchDrawable
			try {
				Field ninePatchField = draw.getClass().getDeclaredField("mNinePatch");
				Field fieldBitmap = ninePatchField.getType().getDeclaredField("mBitmap");
				ninePatchField.setAccessible(true);
				fieldBitmap.setAccessible(true);
				Bitmap temp = (Bitmap) fieldBitmap.get(ninePatchField.get(draw));
				mBitmap = temp;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public BitmapUtil(Bitmap bitmap){
		mBitmap = bitmap;
	}
	
	public BitmapUtil(View view) {
		mBitmap = getBitmapFromView(view);
	}
	
	/**
	 * 
	 * @param count  the count of alpha compare with 
	 * @return
	 */
	public BitmapUtil setSampleCount(int count){
		SAME_COUNT = count;
		return this;
	}
	
	public Rect getNotTranslucentRect(){
		return getNotTranslucentRect(0,0,mBitmap.getWidth(),mBitmap.getHeight());
	}
	
	/**
	 * get a part of translucent {@link Rect} that cut out the {@link BitmapUtil#mBitmap}
	 * @param left   
	 * @param top
	 * @param right
	 * @param bottom
	 * @return
	 */
	public Rect getNotTranslucentRect(int left,int top, int right ,int bottom){
		Rect rect = new Rect();

		if(mBitmap == null){
			ToastAlertUtil.alertError("Error: mBitmap is null", null);
			return rect;
		}
		
		//from right to left
		reset();
		int rightStart = right-1; 
		int rightEnd = left;
//		int rightStart = bitmapWidth-1; 
//		int rightEnd = 0;
		
		for (int i = rightStart ; i > rightEnd ; i--) {
			int piexelY = top + (bottom - top) / 2;
			int value = findNotTranslucentPosition(i, piexelY, i);
			if (value > 0) {
				rect.right = value;
				printLog("right value is " + value);
				break;
			}
		}
		
		//from top to bottom
		reset();
		int topStart = top;
		int topEnd = bottom;
//		int topStart = 0;
//		int topEnd = bitmapHeight;
		
		for (int i = topStart; i < topEnd; i++) {
//			int pixelX = bitmapWidth / 2;
			//矩形内不透明元素的中间的X的坐标
			int pixelX = left + (right - left) / 2;
			int value = findNotTranslucentPosition(pixelX, i, i);
			if (value > 0) {
				rect.top = value;
				printLog("top value is " + value);
				break;
			}
		}
		
		// from bottom to top
		reset();
		int bottomStart = bottom - 1; 
		int bottomEnd = top;
//		int bottomStart = bitmapHeight - 1; 
//		int bottomEnd = 0;
		for (int i = bottomStart ; i >=bottomEnd  ; i--) {
			int pixelX = left + (right - left) / 2;
//			int pixelX = bitmapWidth / 2;
			int value = findNotTranslucentPosition(pixelX, i, i);
			if (value > 0) {
				rect.bottom = value;
				printLog("bottom value is " + value);
				break;
			}
		}
		
		//form left to right
		reset();
		int leftStart = left;
		int leftEnd = right;
//		int leftStart = 0;
//		int leftEnd = bitmapWidth;
		for (int i = leftStart; i < leftEnd; i++) {
//			int pixelY = bitmapHeight / 2;
			int pixelY = top + (bottom - top)/ 2;
			int value = findNotTranslucentPosition(i, pixelY, i);
			if (value > 0) {
				rect.left = value;
				printLog("left value is " + value);
				break;
			}
		}
		
		printLog("rect is " + rect);
		return rect;
	}

	private void printLog(String value) {
		if(DEBUG ){
			slog.p( value);
			
		}
	}

	public int[] getPixelRGB(int pixelX , int pixelY){
		int pixel = mBitmap.getPixel(pixelX, pixelY);
		int[] rgb = new int [3];
		rgb[0] = (pixel & 0xff0000) >> 16;
        rgb[1] = (pixel & 0xff00) >> 8;
        rgb[2] = (pixel & 0xff);
		return rgb;
	}
	
	public String getPixelColor(int pixelX,int pixelY){
		int rgb[] = getPixelRGB(pixelX, pixelY);
		return "#"+Integer.toHexString(rgb[0])+Integer.toHexString(rgb[1])+Integer.toHexString(rgb[2]);
	}
	
	/**
	 * 
	 * @return
	 */
	public ArrayList<Point> getBitmapNoTranslucentStartXValue(){
		reset();
		ArrayList<Point> mStartXValue = new ArrayList<Point>();
		boolean isFound = false;
		for(int i = 0 ; i < mBitmap.getWidth(); i++){
			if(i == 134){
				System.err.println("d");
			}
			int positon = findNotTranslucentPosition(i, mBitmap.getHeight() / 2, i);
			if(positon > 0){
				if(!isFound){
					//found and add
					Point point = new Point();
					point.x = positon;
					mStartXValue.add(point);
					isFound  = true;
					reset();
				}
			}else{
				if(isFound){
					//如果遇到透明像素是0，并且还是发现了一个不透名的像素
					if(mStartXValue.size() > 0) {
						mStartXValue.get(mStartXValue.size() - 1).y = i;
					}
				}
				isFound = false;
			}
		}
		return mStartXValue;
	}
	
	
	/**
	 * find an position that it`s pix not transluncent
	 * @param pixelX 
	 * @param pixelY 
	 * @param position scan position
	 * @return if find , return not transluncent positon ,else return -1
	 */
	protected int findNotTranslucentPosition(int pixelX, int pixelY, int position) {
		int pix = mBitmap.getPixel(pixelX, pixelY);
		int alpha = getPixAlpha(pix);
		if(alpha == 252){//
			//for debug
			System.out.println("");
		}
		if (alpha != 0) {
			if (mLastAlphaValue == alpha) {
				mSameTimes++;
			} else {
				if (mSameTimes <= SAME_COUNT) {
					mSameTimes = 0;
				}
			}

			if (mSameTimes >= SAME_COUNT) {
				boolean forward = position > mLastPosition;
				printLog("position " + position + "  mLastPosition " + mLastPosition + " alpha " + alpha);
				
				if(forward){
					position -= mSameTimes;
				}else{
					position += mSameTimes;
				}
				return position;
			}
			mLastAlphaValue = alpha;
			mLastPosition = position;
		}else{
		}
		slog.d("debug",alpha + "  " + mSameTimes + "  ");
		return -1;
	}

	private void reset() {
		mLastAlphaValue = 0;
		mSameTimes = 0;
		mLastPosition = 0;
	}

	public static int getPixAlpha(int pix) {
		int alpha = (pix & 0xFFFFFFFF) >>> 24;
		return alpha;
	}

	public static Bitmap getBitmapFromView(View view) {  
	    Bitmap bitmap = null;  
	    try {  
	        int width = view.getWidth();  
	        int height = view.getHeight();  
	        if(width != 0 && height != 0){  
	            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);  
	            Canvas canvas = new Canvas(bitmap);  
	            view.layout(0, 0, width, height);  
	            view.draw(canvas);  
	        }  
	    } catch (Exception e) {  
	        bitmap = null;  
	        e.getStackTrace();  
	    }  
	    return bitmap;  
	}

	public static Bitmap createTextBitmap(String text,int width,int height){
		
		Bitmap mutableBitmap = Bitmap.createBitmap(width, height, Config.ALPHA_8);
		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(Color.RED);
		paint.setAntiAlias(true);
		paint.setTextSize(35);
		paint.setTextAlign(Paint.Align.LEFT);
		FontMetrics metrics = paint.getFontMetrics();
		// 计算每一个坐标    
		float baseX = 0;    
		float baseY = 100;    
		slog.p(ObjectUtil.showObjectField(metrics));
		
		Canvas canvas = new Canvas(mutableBitmap);
		float textX = 0;
		float textY = 35;
		canvas.drawText(text, baseX, baseY, paint);  
		canvas.drawText(text,textX, textY, paint);
		canvas.drawLine(0, textY, 300, textY, paint);
		canvas.drawLine(textX, 0, textX, 300, paint);
		return mutableBitmap;
	}
    public static Bitmap createRoundRectBitmap(Bitmap srcBitmap,
                                               int rx,
                                               int ry,
                                               int xOffSet,
                                               int yOffSet

    ) {
        if(srcBitmap == null){
            return null;
        }
        Bitmap desBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.ARGB_8888);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        Canvas canvas = new Canvas(desBitmap);

        paint.setColor(Color.RED);

        canvas.drawRoundRect(
                new RectF(xOffSet,yOffSet,srcBitmap.getWidth() - xOffSet,
                        srcBitmap.getHeight() - yOffSet),
                rx,
                ry,
                paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(srcBitmap,0,0,paint);
        return desBitmap;
    }
    public static Bitmap createRoundRectBitmap(Bitmap srcBitmap, int rx, int ry) {
        return createRoundRectBitmap(srcBitmap,rx,ry,0,0);
    }


}
